package com.zhangwei.xmppdemo.xmpp;

import android.os.AsyncTask;
import android.util.Log;

import com.zhangwei.xmppdemo.xmpp.api.XmppCallBack;

import org.jivesoftware.smack.ConnectionConfiguration;
import org.jivesoftware.smack.SmackException;
import org.jivesoftware.smack.XMPPConnection;
import org.jivesoftware.smack.XMPPException;
import org.jivesoftware.smack.packet.Presence;
import org.jivesoftware.smack.roster.Roster;
import org.jivesoftware.smack.roster.RosterEntry;
import org.jivesoftware.smack.tcp.XMPPTCPConnection;
import org.jivesoftware.smack.tcp.XMPPTCPConnectionConfiguration;
import org.jivesoftware.smackx.iqregister.AccountManager;
import org.jivesoftware.smackx.vcardtemp.VCardManager;
import org.jivesoftware.smackx.vcardtemp.packet.VCard;

import java.util.Collection;
import java.util.Map;


/**
 * @version V1.0
 * @description:
 * @title: Expands
 * @package com.zhangwei.xmppdemo.xmpp
 * @author: zhangwei
 * @date: 2015-12-19 下午4:38
 */
public class XmppConnection {
    private int SERVER_PORT = 5222;
    private static final String SERVICE_NAME = "www.qianfeng.com";
    private static final int SERVICE_PORT = 5222;
    private static final String SERVICE_HOST = "10.6.155.52";
    private XMPPTCPConnection connection;
    private static XmppConnection xmppConnection = new XmppConnection();
    private TaxiConnectionListener connectionListener;

    private static final String USED_RESOURCE = "Android";

    synchronized public static XmppConnection getInstance() {
        return xmppConnection;
    }

    /**
     * 创建连接
     */
    public XMPPTCPConnection getConnection() {
        if (connection == null) {
            openXmppTCPConnection();
        }
        return connection;
    }

    /**
     * 打开连接
     */
    private boolean openXmppTCPConnection() {
        //如果未连接服务器
        if (null == connection || !connection.isAuthenticated()) {
            try {
                XMPPTCPConnectionConfiguration.Builder builder = XMPPTCPConnectionConfiguration.builder();
                builder.setServiceName(SERVICE_NAME);
                builder.setHost(SERVICE_HOST);
                builder.setPort(SERVICE_PORT);
                //开启debug模式  方便测试
                builder.setDebuggerEnabled(true);
                //设置数据是否压缩
                builder.setCompressionEnabled(true);
                //  状态设为离线，目的为了取离线消息
                builder.setSendPresence(true);
                //禁用TLS协议
                builder.setSecurityMode(ConnectionConfiguration.SecurityMode.disabled);
                XMPPTCPConnectionConfiguration configuration = builder.build();
                connection = new XMPPTCPConnection(configuration);
                connection.connect();
                return true;
            } catch (Exception e) {
                e.printStackTrace();
                connection = null;
            }
        }
        return false;
    }

    /**
     * 关闭连接
     */
    public void closeConnection() {
        if (connection != null) {
            //移除连接监听
            //connection.removeConnectionListener(connectionListener);
            if (connection.isConnected())
                connection.disconnect();
            connection = null;
        }
    }


    /**
     * 登录
     *
     * @param account  登录帐号
     * @param password 登录密码
     * @return
     */

    public void login(final String account, final String password, final XmppCallBack<Integer> callBack) {

        new AsyncTask<Void, Void, Integer>() {


            @Override
            protected void onPreExecute() {
                super.onPreExecute();
                if (callBack != null) {
                    callBack.onStart();
                }
            }

            @Override
            protected Integer doInBackground(Void... params) {
                int state = -1;
                try {
//                    getConnection().login(account, password);
                    /**
                     * 用户名
                     * 密码
                     * 登陆平台
                     */
                    getConnection().login(account, password, USED_RESOURCE);
                    Presence presence = new Presence(Presence.Type.available);
                    //发送用户状态在线
                    getConnection().sendStanza(presence);
                    connectionListener = new TaxiConnectionListener();
                    getConnection().addConnectionListener(connectionListener);
                    state = 1;
                } catch (Exception e) {
                    e.printStackTrace();
                }
                return state;
            }

            @Override
            protected void onPostExecute(Integer integer) {
                super.onPostExecute(integer);
                if (callBack != null) {
                    callBack.onSuccess(integer);
                }
            }
        }.execute();
    }

    /**
     * 注册
     *
     * @param account  注册帐号
     * @param password 注册密码
     * @return 1、注册成功 0、服务器没有返回结果 , 2、这个账号已经存在 3  注册失败
     */

    public void register(final String account, final String password, final Map<String, String> attributes, final XmppCallBack<Integer> callBack) {
        new AsyncTask<Void, Void, Integer>() {
            @Override
            protected void onPreExecute() {
                super.onPreExecute();
                if (callBack != null) {
                    callBack.onStart();
                }
            }
            @Override
            protected Integer doInBackground(Void... params) {
                int state = -1;
                AccountManager manager = AccountManager.getInstance(getConnection());
                try {
                    manager.createAccount(account, password);
                } catch (SmackException.NoResponseException e) {
                    e.printStackTrace();
                    state = 0;
                } catch (XMPPException.XMPPErrorException e) {
                    e.printStackTrace();
                    String msg = e.getMessage();
                    boolean b = msg.toString().equalsIgnoreCase("conflict(409)");
                    if (b) {
                        state = 2;
                    }
                } catch (SmackException.NotConnectedException e) {
                    e.printStackTrace();
                    state = 3;
                }
                return state;
            }

            @Override
            protected void onPostExecute(Integer integer) {
                super.onPostExecute(integer);
                if (callBack != null) {
                    callBack.onSuccess(integer);
                }
            }
        }.execute();
    }

    /**
     * 更改用户状态
     */
    public void setPresence(int code) throws SmackException.NotConnectedException {
        if (connection == null)
            return;
        Presence presence;
        switch (code) {
            case 0:
                presence = new Presence(Presence.Type.available);
                connection.sendStanza(presence);
                Log.v("state", "设置在线");
                break;
            case 1:
                presence = new Presence(Presence.Type.available);
                presence.setMode(Presence.Mode.chat);
                connection.sendStanza(presence);
                Log.v("state", "设置Q我吧");
                System.out.println(presence.toXML());
                break;
            case 2:
                presence = new Presence(Presence.Type.available);
                presence.setMode(Presence.Mode.dnd);
                connection.sendStanza(presence);
                Log.v("state", "设置忙碌");
                System.out.println(presence.toXML());
                break;
            case 3:
                presence = new Presence(Presence.Type.available);
                presence.setMode(Presence.Mode.away);
                connection.sendStanza(presence);
                Log.v("state", "设置离开");
                System.out.println(presence.toXML());
                break;
            case 4:
                Roster roster = Roster.getInstanceFor(getConnection());
                Collection<RosterEntry> entries = roster.getEntries();
                for (RosterEntry entry : entries) {
                    presence = new Presence(Presence.Type.unavailable);
                    presence.setStanzaId(presence.getStanzaId());
                    presence.setFrom(getConnection().getUser());
                    presence.setTo(entry.getUser());
                    connection.sendStanza(presence);
                    System.out.println(presence.toXML());
                }
                // 向同一用户的其他客户端发送隐身状态
                presence = new Presence(Presence.Type.unavailable);
                presence.setStanzaId(presence.getStanzaId());
                presence.setFrom(connection.getUser());
//                presence.setTo(StringUtils.parseBareAddress(connection.getUser()));
                connection.sendStanza(presence);
                Log.v("state", "设置隐身");
                break;
            case 5:
                presence = new Presence(Presence.Type.unavailable);
                connection.sendStanza(presence);
                Log.v("state", "设置离线");
                break;
            default:
                break;
        }
    }

    /**
     * 修改密码
     *
     * @param pwd
     * @return
     */
    public boolean changePassword(String pwd) {
        try {
            AccountManager.getInstance(getConnection()).changePassword(pwd);
            return true;
        } catch (Exception e) {
            return false;
        }
    }

    public void changeUserInfo() {
    }

    /**
     * 删除当前用户
     *
     * @param connection
     * @return
     */
    public boolean deleteAccount(XMPPConnection connection) {
        try {
            AccountManager.getInstance(connection).deleteAccount();
            return true;
        } catch (Exception e) {
            return false;
        }
    }

    /**
     * 获取用户VCard信息
     *
     * @param
     * @param bareJid
     * @return
     * @throws XMPPException
     */
    public VCard getUserVCard(String bareJid) {
        if (getConnection() == null)
            return null;
        VCard vCard = null;
        VCardManager vm = VCardManager.getInstanceFor(getConnection());
        try {
            vCard = vm.loadVCard(bareJid);
        } catch (XMPPException e) {
            e.printStackTrace();
        } catch (SmackException.NotConnectedException e) {
            e.printStackTrace();
        } catch (SmackException.NoResponseException e) {
            e.printStackTrace();
        }
        return vCard;
    }

}


